package com.hh.core.aop;

import java.lang.reflect.Method;

import javax.naming.NoPermissionException;

import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.annotation.Around;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Pointcut;
import org.aspectj.lang.reflect.MethodSignature;
import org.springframework.stereotype.Component;

import cn.hutool.core.util.ArrayUtil;

import com.hh.core.annotion.Permission;
import com.hh.core.shiro.check.PermissionCheckManager;
import com.hh.core.shiro.util.ShiroUtil;

/**
 * 
* @ClassName: PermissionAop  
* @Description: TODO(自定义 aop 拦截器类，拦截判断所有使用@Permission的方法。用于验证用户是否有权限访问或使用当前方法)  
* @author hxn
* @date 2018年1月18日 上午10:51:58  
*
 */
@Aspect
@Component
public class PermissionAop {

	/**
	 * 
	* @Title: cutPermission  
	* @Description: 指定 aop 切面为使用@permission 注释的方法  
	* @param     设定文件  
	* @return void    返回类型  
	* @author hxn
	* @date 2018年1月18日 上午10:53:15  
	* @throws
	 */
    @Pointcut(value = "@annotation(com.hh.core.annotion.Permission)")
    private void cutPermission() {}
    
    /**
     * 
    * @Title: doPermission  
    * @Description:   指定 aop 处理为环绕，用于进行权限验证
    * @param @param point
    * @param @return
    * @param @throws Throwable    设定文件  
    * @return Object    返回类型  
    * @author hxn
    * @date 2018年1月18日 上午10:53:23  
    * @throws
     */
    @Around("cutPermission()")
    public Object doPermission(ProceedingJoinPoint point) throws Throwable {
    	if(ShiroUtil.isAdmin()){    //是否为超级管理员
    		return point.proceed();     
    	}
    	//从 Aop 切入点获取方法
        MethodSignature ms = (MethodSignature) point.getSignature();
        //获取方法
        Method method = ms.getMethod();
        //获取方法上的@permission 注释
        Permission permission = method.getAnnotation(Permission.class);
        //获取方法上@permission 的值
        Object[] permissions = permission.value();
        //检查指定角色
        if(ArrayUtil.isNotEmpty(permissions) && PermissionCheckManager.check(permissions)){
        	return point.proceed();
        }
        
        //检查全体角色
        boolean result = PermissionCheckManager.checkAll();
        if (result) {
            return point.proceed();
        } else {
            throw new NoPermissionException();
        }
    }
}
